home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / neuron.zip / NEURON.C < prev    next >
C/C++ Source or Header  |  1992-07-06  |  34KB  |  925 lines

  1. /* Multilayers and/or interconnected network models             */
  2. /* Enable many networks study                                   */
  3. /* of auto-associated networks (Preceptron, Hopfield)           */
  4. /* Computation module                                           */
  5.  
  6. /* TC 2.0       NEURON.C        E.FARHI                         
  7.         versions: 0.0   09/91 experimental version 
  8.                   1.0   10/91 multi-layers network
  9.                   2.0   11/91 first version of a multi-model network
  10.                   2.1   01/92 adding learn_opt
  11.                   2.2   02/92 debugging, add noise
  12.                   2.3   03/92 debug, simulated tempering
  13.                   2.5   05/92 modifying learn_opt, add SHAKER
  14.                               learn_verify */
  15.                   
  16. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  17. /*                      VERSION 2.5                             */
  18. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  19.                   
  20.                   
  21. /* ------------------------------------------------------------ */
  22. /* initialization beginning                                     */
  23. /* ------------------------------------------------------------ */
  24.  
  25.  
  26. /* Library uses                                                 */
  27.  
  28. #include <math.h>       /* for exp                              */
  29. #include <stdlib.h>     /* for random and malloc                */
  30. #include <time.h>       /* for network init on internal clock   */
  31. #include <stdio.h>      /* for printf(debugging)                */
  32.  
  33. /* Every printf can be removed for a tranparent use             */
  34.  
  35. /* Network Constants --------------------------------------     */
  36. /* internal use                                                 */
  37.  
  38. #define NB_LAYERS_MAXI  3       /* defines the maxi nb of different layers */
  39. #define NB_LEVELS_MAXI 3        /* defines the maxi nb of levels NB_LEV>=NB_LAY is better */
  40. #define NB_N_LAYER_MAXI 40      /* nb maxi of neurons in a layer*/
  41. #define NB_BACKP_MAXI   10      /* before shaker                */
  42. #define LEARN_FAIL      1000    /* test for learning failure    */
  43. #define MAX_RAND        32767.0
  44.  
  45. #define TEMPERING_OFF   0
  46. #define TEMPERING_ON    255     /* some different tempering modes */
  47.  
  48. #define MSG_NOISE       1       /* enables an external use      */
  49. #define MSG_STD         0
  50. #define MSG_ERR         255
  51.  
  52. /* Definition of 'networks' types ----------------------------- */
  53. /* You can add things if you wish                               */
  54.  
  55. typedef struct
  56.         {
  57.           char activity;                /* if neuron active     */
  58.         } FLAG_N;                       /* neuron flag  */
  59.  
  60. typedef struct
  61.         {
  62.           char interconnection  ;       /* if Hopfield layer    */        
  63.           char bias             ;       /* if 0, no bias        */
  64.         } FLAG_L;                       /* flag for layer       */
  65.         
  66. typedef struct
  67.         {
  68.           float intra[NB_N_LAYER_MAXI]; /* INTRA-layer weight, bi-directional link, Hopfield type */
  69.           float sum,                    /* weight sum           */
  70.                 state,                  /* neural state=f(sum)  */
  71.                 loc_err,                /* local weight error   */
  72.                 bias;                   /* neural bias  */
  73.           FLAG_N flag;                    
  74.         } NEURONS;                      /* formal neuron model          */
  75.  
  76. /* note :  high or low  state                           */
  77.         
  78.  
  79. typedef struct                          /* struct containing every infos for a network */
  80.         {
  81.           int nb_layers,                        /* nb of diferent layers in the net */
  82.               nb_n_layer[NB_LAYERS_MAXI],       /* neurons nb in a layer*/
  83.               nb_levels,                        /* levels nb in the network */
  84.               layer_order[NB_LEVELS_MAXI];      /* layer order          */
  85.                         /* some layers can be used for diferent levels */
  86.           FLAG_L flag[NB_LAYERS_MAXI];           
  87.           float err_threshold,                      /* for learning end        */
  88.                 coefficient,                    /* accentuate weight=links variations in the gradient */
  89.                 coef_out;                       /* output coefficient for continuum neuron */
  90.  
  91.           float beta,                           /* 1/thermo temperature   */
  92.                 high_threshold,                 /* potential thresholds for short mem */
  93.                 low_threshold,
  94.                 weight_threshold,               /* threshold for synaptic links */
  95.                 threshold,                      /* bascule threshold for learning and sigmoid */
  96.                 noise,                          /* noise for synaptic pot */
  97.                 high_state,                     /* state bounds for neurons */
  98.                 low_state;
  99.                 
  100.           unsigned char tempering;              /* simulated tempering */
  101.           float t_tempering_max,
  102.                 t_tempering_min,
  103.                 cte_tempering;
  104.           
  105.           float energy; 
  106.  
  107.           float inter[NB_LEVELS_MAXI][NB_N_LAYER_MAXI][NB_N_LAYER_MAXI];
  108.                /* INTER-levels coefs lev->lev+1 multi-perceptron */
  109.           
  110.           NEURONS neuron[NB_N_LAYER_MAXI][NB_LAYERS_MAXI];
  111.         } NETWORKS;     /* ISN'T IT BIG ? */
  112.                
  113. /* NOTE: layer = phisical neuron layer                  */
  114. /*       level = logical neuron layer                   */
  115.         
  116. /* local variables                                      */
  117.  
  118. char msg_prg=0;        /* global message */
  119.         
  120.  
  121. /* procedures declaration ------------------------------ */
  122.  
  123. /* NB : Have a look at the doc                           */
  124.  
  125. float sqr(float);
  126. float Rnd(float);
  127. float sigmoid(float,float,float);
  128. float sigmoid_derivative(float,float,float);
  129. int   *list_norm(int);
  130. int   *list_alea(int,int);
  131. float in_limits(float,float,float);
  132. int   equal(float,float);
  133.  
  134. float weight_sum(NETWORKS  *,int,int);          /* important */
  135. float level_state(NETWORKS  *,int);             /* important */
  136. float level_tempering(NETWORKS  *,int);
  137. float network_state(NETWORKS  *,float[]);
  138. float neuron_state(NETWORKS  *,float);
  139.  
  140. float backpropagation(NETWORKS  *,float[],float[]);     /* important */
  141. float learn_prototype(NETWORKS  *,int[],int,float[],float[],int);
  142. float learn_list(NETWORKS  *,int[],int,float[],float[]);
  143. int   learn_opt(NETWORKS  *,int[],int,float[],float[]); /* important */
  144. int   learn_norm(NETWORKS  *,int[],int,float[],float[]);
  145. int   learn_test(NETWORKS  *,int,long,long);
  146.  
  147. void  init_alea_network(NETWORKS  *);
  148. void  init_0_network(NETWORKS  *);
  149. void  init_flag_network(NETWORKS  *,int,int,int,int);
  150. void  init_var_network(NETWORKS  *,float,float,float,float,float,float,float,float,float,float,float,float,float,float);
  151.  
  152. float sqr_sum(NETWORKS  *);
  153. float compare_output(NETWORKS  *,float[]);
  154. float learn_verify(NETWORKS  *,int[],int,float[],float[]);
  155. void  print_network(NETWORKS  *);
  156. void  info_struct_network(NETWORKS  *);
  157. void  info_vars_network(NETWORKS  *);
  158.  
  159.  
  160.  
  161.  
  162. /* ------------------------------------------------------------ */
  163. /* procedures definition beginning                              */
  164. /* ------------------------------------------------------------ */
  165.  
  166.  
  167.  
  168. float sqr(float x)              /* mysterious procedure... */
  169. {
  170.   return(x*x);
  171. }
  172.  
  173. float Rnd(float x)              /* sends back a float between 0 and x */
  174. {
  175.   float rnd;
  176.   
  177.   rnd=(float)rand()/MAX_RAND*x;
  178.   return(rnd);
  179. }  
  180.  
  181. float sigmoid(float beta, float sum, float threshold)     /* sigmoid function */
  182. {                                        /* = transfert function */
  183.   int beta2=abs(beta);
  184.  
  185.   return(1/(1+exp(-2*beta2*(sum-threshold))));
  186. }                                       /* usually threshold=0   */
  187.  
  188. float sigmoid_derivative(float beta, float sum, float threshold)
  189. {                                       /* just guess */
  190.   float s;
  191.   s=sigmoid(beta,sum,threshold);
  192.   return(s*(1-s));
  193. }
  194.  
  195. /* procedures for defining a learning pedagogy  */
  196.  
  197. int *list_alea(size_line,nb_prototypes)     /* generate a random list to learn */
  198. int size_line;
  199. int nb_prototypes;
  200. {
  201.   int *list;
  202.   int i;
  203.   
  204.   list=malloc((size_line+1)*sizeof(int));
  205.   for (i=0; i<=size_line; i++)
  206.     list[i]=(int)(rand()*(nb_prototypes+1)/32768.0);
  207.   return(list);
  208. }
  209.  
  210. int *list_norm(nb_prototypes)                /* genarate the normal list */
  211. int nb_prototypes;
  212.   int *list;
  213.   int i;
  214.   
  215.   list=malloc((nb_prototypes+1)*sizeof(int));
  216.   for (i=0; i<=nb_prototypes; i++)
  217.     list[i]=i;
  218.   return(list);
  219. }
  220.  
  221. float in_limits(float x, float high, float low) /* to remain between bounds */
  222. {
  223.   float tmp=x;
  224.  
  225.   if (tmp>high) tmp=high;
  226.   else
  227.     if (tmp<low) tmp=low;
  228. /*  if (x != tmp)
  229.     printf("\a");*/
  230.   return (tmp);  
  231. }    
  232.  
  233. int equal(float var,float ref)  /* equal to within 1 % */
  234. {
  235.   return ((var<ref*1.01) && (var>0.99*ref));
  236. }  
  237.  
  238.  
  239. /* ------------------------------------------------------------ */
  240. /*              network state procedures                        */
  241. /* ------------------------------------------------------------ */
  242.  
  243.  
  244. float weight_sum(NETWORKS  *network,int neuron,int level)
  245. {                       /* weight sum of a neuron in a level */
  246.   int n,c,c_1;
  247.   float b,s=0;
  248.  
  249.   c=(*network).layer_order[level];            /* layer of a level */
  250.   if ((*network).neuron[neuron][c].flag.activity)       /* activee neuron ? */
  251.   {
  252.     s=(*network).neuron[neuron][c].bias;
  253.     if ((*network).flag[c].interconnection)      /* Hopfield ? */
  254.       for (n=0; n<=(*network).nb_n_layer[c]; n++)       /* INTRA-layer Hopfield sum */
  255.         s+=(*network).neuron[n][c].state*(*network).neuron[neuron][c].intra[n];
  256.     if (level >= 1)                            /* not the input layer */
  257.     {
  258.       c_1=(*network).layer_order[level-1];    /* preceding level */
  259.       for (n=0; n<=(*network).nb_n_layer[c_1]; n++)
  260.                                                 /* INTER-level perceptron sum */
  261.         s+=(*network).neuron[n][c_1].state*(*network).inter[level-1][n][neuron];
  262.     }           /* sends back s=0 if  inactiv or Perceptron input */
  263.   }
  264.   b=Rnd(2*(*network).noise)-(*network).noise;   /* add some noise */
  265.   if (s==0)
  266.     s=b/(*network).beta;
  267.   else
  268.     s*=1+b;
  269.   s=in_limits(s,(*network).high_threshold,(*network).low_threshold);
  270.  
  271.   return (s);
  272. }
  273.  
  274. float neuron_state(NETWORKS  *network,float s)
  275. {       /* for computing neural state */
  276.   float proba,state;
  277.  
  278.   proba=sigmoid((*network).beta,s,(*network).threshold);
  279.   if ((*network).beta<0)
  280.   {     /* stochastic neuron */
  281.     if (Rnd(1)<proba)
  282.       state=(*network).high_state;
  283.     else
  284.       state=(*network).low_state;
  285.   }    
  286.   else  /* continuum neuron */
  287.     state=((*network).high_state-(*network).low_state)*proba+(*network).low_state;      /* state continu entre -1 et 1 */
  288.   return(state);
  289. }
  290.  
  291. /* if T<0 it is a stochastic neuron                     */
  292. /* if T -> 0 the neuron becomes determinist             */
  293.    
  294. float level_state(NETWORKS  *network,int level)
  295. {       /* compute the state of a logic layer */
  296.   int layer,neuron;
  297.   float s,state2,
  298.         energy=0;                     /* level energy */
  299.   float state[NB_N_LAYER_MAXI][NB_LAYERS_MAXI];      
  300.  
  301.   layer=(*network).layer_order[level];
  302.   for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  303.   {
  304.     s=weight_sum(network,neuron,level);   /* synaptic potential */
  305.     state2=neuron_state(network,s);
  306.     state[neuron][layer]=state2;
  307.     if (level != 0)
  308.     {
  309.       energy+=state2*s;         /* energy=sum(i<>j)[-.5*Jij.Etat(i).Etat(j) ] */
  310.       (*network).neuron[neuron][layer].sum=s;   /* saving results, parallel calculation  */
  311.     }  
  312.  
  313.   }
  314.   if ((level>0) || ((*network).flag[layer].interconnection))
  315.         /* input unmodified exept for Hopfield */
  316.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  317.                                 /* network=network0 */
  318.       (*network).neuron[neuron][layer].state=state[neuron][layer];
  319.        
  320.   return(-0.5*energy);
  321. }
  322.  
  323.         
  324. float network_state(NETWORKS  *network,float input[])
  325. {       /* network state */
  326.   int neuron,
  327.       layer,
  328.       level;
  329.   float energy=0;    
  330.   
  331.   layer=(*network).layer_order[0];    
  332.   for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  333.     (*network).neuron[neuron][layer].state=input[neuron];
  334.                                 /* imposing an input */
  335.   for (level=0; level<=(*network).nb_levels; level++)
  336.     energy+=level_state(network,level);
  337.                                 /* progressing towards output  */
  338.   (*network).energy=energy;
  339.   return(energy);       /* network energy */
  340. }
  341.  
  342. /* ------------------------------------------------------------ */
  343. /*                      learning procedures                     */
  344. /* ------------------------------------------------------------ */
  345.  
  346. float backpropagation(NETWORKS  *network,float input[],float output[])     /* procedure d'apprentissage simple */
  347. {       /* gradient backpropagation algorithm */
  348.   int neuron,
  349.       layer,
  350.       layer1,           /* next layer           */
  351.       layer_1,          /* preceding layer      */
  352.       level,
  353.       n;
  354.   float error,
  355.         var,
  356.         err_tot=0;              /* global network error */      
  357.         
  358.   network_state(network,input);  
  359.   for (level = (*network).nb_levels; level >= 0; level--)
  360.   {                             /* progressing towards input */
  361.     layer=(*network).layer_order[level];
  362.     if (level > 0)                      /* except input */
  363.       layer_1=(*network).layer_order[level-1];
  364.     if (level < (*network).nb_levels)   /* except output */
  365.       layer1=(*network).layer_order[level+1];
  366.  
  367.     /*                  error caculation                */
  368.  
  369.     for (neuron = 0; neuron <= (*network).nb_n_layer[layer]; neuron++)
  370.     {
  371.       error=0;
  372.       if (level < (*network).nb_levels)
  373.       {                         /* error coming from the next layer */
  374.         for (n = 0; n <= (*network).nb_n_layer[layer1]; n++)
  375.                         /* on next layer : inter layer Perceptron */
  376.           error+=(*network).neuron[n][layer1].loc_err*(*network).inter[level][neuron][n];
  377.       } 
  378.       else
  379.       {                         /* output layer */
  380.         error=(*network).neuron[neuron][layer].state-output[neuron];
  381.         err_tot+=0.5*error*error;
  382.       }                         /* rough error */
  383.  
  384.       error*=sigmoid_derivative((*network).beta,(*network).neuron[neuron][layer].sum,(*network).threshold);
  385.       (*network).neuron[neuron][layer].loc_err=error;   /* local partial error (non Hopfield) */
  386.     }
  387.         
  388.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  389.     {
  390.       error=(*network).neuron[neuron][layer].loc_err;
  391.       if ((*network).flag[layer].interconnection)
  392.       {
  393.         var=sigmoid_derivative((*network).beta,(*network).neuron[neuron][layer].sum,(*network).threshold);
  394.         for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  395.           error+=(*network).neuron[n][layer].loc_err*(*network).neuron[neuron][layer].intra[n]*var;  
  396.         (*network).neuron[neuron][layer].loc_err=error; /* local error  */
  397.       }
  398.  
  399.         /*              modifying weights                       */
  400.  
  401.       error*=-(*network).coefficient;   /* accentuates the weight variation */
  402.       if ((*network).flag[layer].bias) 
  403.                                 /* else bias remains at 0 */
  404.       {                          
  405.         var=(*network).neuron[neuron][layer].bias+error;
  406.         (*network).neuron[neuron][layer].bias=in_limits(var,(*network).weight_threshold,-(*network).weight_threshold);
  407.       }    
  408.       
  409.       if ((*network).flag[layer].interconnection)
  410.         for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  411.                                 /* var intra weight */
  412.         {  
  413.           var=(*network).neuron[neuron][layer].intra[n]+error*(*network).neuron[n][layer].state;
  414.           (*network).neuron[neuron][layer].intra[n]=in_limits(var,(*network).weight_threshold,-(*network).weight_threshold);
  415.         }
  416.       if (level > 0)
  417.         for (n=0; n<=(*network).nb_n_layer[layer_1]; n++)
  418.                                 /* var inter weight */
  419.         {  
  420.           var=(*network).inter[level-1][n][neuron]+error*(*network).neuron[n][layer_1].state;
  421.           (*network).inter[level-1][n][neuron]=in_limits(var,(*network).weight_threshold,-(*network).weight_threshold);
  422.         }
  423.     }
  424.   }
  425.   return(err_tot);
  426. }
  427.  
  428. float learn_prototype(NETWORKS  *network,int list_prototypes[],int k,float inputs[],float outputs[],int nb_proto)
  429. {       /* learns a prototype to the net nb_proto times */
  430.   int j,NCin,NCout,nb_back=0,noise=0;
  431.   float err_tot,t,t0;           /* output error */
  432.   float input[NB_N_LAYER_MAXI],
  433.         output[NB_N_LAYER_MAXI];
  434.  
  435.                 /* neurons nb in 1st and last level */          
  436.   NCin=(*network).nb_n_layer[(*network).layer_order[0]];
  437.   NCout=(*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]];
  438.  
  439.   for (j=0; j<=NCin; j++)       /* extract first prototype=(input,output) */
  440.   input[j]=inputs[list_prototypes[k]*(NCin+1)+j];  
  441.   for (j=0; j<=NCout; j++)
  442.   output[j]=outputs[list_prototypes[k]*(NCout+1)+j];
  443.  
  444.   t0=1/(*network).beta;
  445.   if (msg_prg==MSG_NOISE)
  446.   {
  447.     printf(" with SHAKER ");
  448.     noise=(*network).noise;
  449.     (*network).noise*=2;        /* noise */
  450.     msg_prg=MSG_STD;
  451.   }
  452.     
  453.   do
  454.   {             /* possibly simulated tempering */
  455.     t=-1;
  456.     if ((noise>0) && ((*network).tempering != TEMPERING_OFF))   /* thermic noise */
  457.     {
  458.       t=(*network).t_tempering_min+(*network).t_tempering_max*exp(-(float)nb_back/(*network).cte_tempering);
  459.       printf(".");
  460.     }  
  461.     if (t<t0) t=t0;
  462.     nb_back++;
  463.     err_tot=backpropagation(network,input,output);
  464.   }  
  465.   while (nb_back<nb_proto);
  466.   (*network).beta=1/t0;
  467.   return(err_tot);              /* sends back prototype error */
  468. }
  469.  
  470. float learn_list(NETWORKS  *network,int list_prototypes[],int size_list,float inputs[],float outputs[])       /* supervising learning */
  471.  
  472. /* int list_prototypes[];       prototype order to learn */
  473. /* int size_list;               prototypes nb in list */
  474. /* float inputs[],outputs[];    prototypes to learn */
  475.  
  476. {
  477.   int k;
  478.   float err_cumul=0;                    /* error sobre todos los prototypes */
  479.  
  480.   for (k=0; k<=size_list; k++)         /* let's read the list */
  481.     err_cumul+=learn_prototype(network,list_prototypes,k,inputs,outputs,1);
  482.   return(err_cumul/(size_list+1));
  483.                 /* sends back the mean prototype error */
  484. }
  485.  
  486.  
  487. int learn_opt(NETWORKS  *network,int list_prototypes[],int size_list,float inputs[],float outputs[])        /* learn en favorisant les prototypes mal connus */
  488. {       /* we need the normal list *list_norm(..)={1,2,..,n}      */
  489.         /* optimized learning                                   */
  490.   int k,i=0;
  491.   float error_mean,
  492.         error_m,error_m0,
  493.         err_max,err_max0,
  494.         error,
  495.         noise=(*network).noise;
  496.   int *priority_proto;
  497.  
  498.   priority_proto=(int *)malloc((size_t)sizeof(int)*(size_list+1));
  499.   error_mean=(*network).err_threshold*4;
  500.   error_m0=0;
  501.   err_max0=0;
  502.   for (k=0; k<=size_list; k++)  /* init learning priority */
  503.     priority_proto[k]=1;
  504.   do
  505.   {
  506.     error_m=0;
  507.     err_max=0;
  508.     printf("\nI learn all prototypes especially those I don't know well.\n");
  509.     for (k=0; k<=size_list; k++)       /* looking for the unknown prototype and error max */
  510.     {
  511.       error=learn_prototype(network,list_prototypes,k,inputs,outputs,priority_proto[k]);
  512.       error_m+=error;
  513.       if (err_max<error) err_max=error;
  514.       i+=priority_proto[k];
  515.       printf("\nPrototype No: %3i. Priority %3i. Error: %5.2f. Energy %4.1f.",k,priority_proto[k],error,(*network).energy);
  516.       if (error>=error_mean*1.05)
  517.         if (priority_proto[k]<NB_BACKP_MAXI)
  518.           priority_proto[k]++;
  519.         else
  520.         {
  521.           msg_prg=MSG_NOISE;  
  522.           priority_proto[k]/=2;
  523.         }  
  524.       else 
  525.         if ((error<=error_mean*.95) && (priority_proto[k]>1))
  526.           priority_proto[k]--;
  527.     }
  528.     error_mean=error_m/(size_list+1);
  529.     printf("\nTurn: %3i. Mean error %5.2f. Max error %5.2f.",i,error_mean,err_max);
  530.     if ((equal(error_m,error_m0)) && (equal(err_max,err_max0)))
  531.     {
  532.       (*network).noise*=2;
  533.       printf("\nGlobal Shaker");
  534.     }
  535.     else
  536.     {
  537.       error_m0=error_m;
  538.       err_max0=err_max;
  539.       (*network).noise=noise;
  540.     }
  541.   }
  542.   while ((err_max>=(*network).err_threshold) && (i<=LEARN_FAIL));
  543.   if (i==LEARN_FAIL) i*=-1;
  544.   return (i);   /* sends back the number of learning turns */
  545. }
  546.  
  547. int learn_norm(NETWORKS  *network,int list_lots[],int size_list,float inputs[],float outputs[])
  548. {       /* learn a prototype list */
  549.   int n=0;
  550.   float err;
  551.  
  552.   do
  553.   {
  554.     err=learn_list(network,list_lots,size_list,inputs,outputs);
  555.     printf("\nError: %4.3f",err);
  556.     n++;
  557.   }
  558.   while (err>(*network).err_threshold);
  559.   return (n);
  560. }
  561.  
  562. int learn_test(NETWORKS  *network,int nb_prototypes,long sizein,long sizeout)
  563. {               /* test the validity of prototypes */
  564.   int flag=1;
  565.   
  566.   if (((*network).nb_n_layer[(*network).layer_order[0]]*(nb_prototypes+1)>(sizein/sizeof(float)))
  567.   || ((*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]]*(nb_prototypes+1)>(sizeout/sizeof(float))))
  568.     flag=0;
  569.   
  570.   return(flag);
  571. }
  572.  
  573. /* ------------------------------------------------------------ */
  574. /*              Initialization of networks                      */
  575. /* ------------------------------------------------------------ */    
  576.  
  577.   
  578.  
  579. void init_alea_network(NETWORKS  *network)
  580. {             /* initialize a random network */
  581.   int neuron,
  582.       layer,
  583.       level,
  584.       n,
  585.       lay_sup,nb_lev,nb_neuron,nb_neuron_sup;
  586.   float s; 
  587.            
  588.   srand((unsigned)clock());     /* used because it is portable */
  589.                 /* initialize random generator with the clock */
  590.   for (layer=0; layer<=(*network).nb_layers; layer++)
  591.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  592.     {
  593.       if ((*network).flag[layer].bias) 
  594.         (*network).neuron[neuron][layer].bias=Rnd(0.5)-0.25;
  595.       else
  596.         (*network).neuron[neuron][layer].bias=0;
  597.       s=Rnd(4)-2;
  598.       (*network).neuron[neuron][layer].sum=s;
  599.       (*network).neuron[neuron][layer].state=neuron_state(network,s);
  600.       (*network).neuron[neuron][layer].loc_err=0;
  601.        
  602.       for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  603.         if ((*network).flag[layer].interconnection)
  604.           (*network).neuron[neuron][layer].intra[n]=Rnd(0.5)-0.25;
  605.         else
  606.           (*network).neuron[neuron][layer].intra[n]=0;
  607.     }
  608.   nb_lev=(*network).nb_levels-1;                /* nb of levels except the last */   
  609.   for (level=0; level<=nb_lev; level++)
  610.     {
  611.     layer=(*network).layer_order[level];        /* layer No level */
  612.     nb_neuron=(*network).nb_n_layer[layer];     /* nb of neuron in the level */
  613.     lay_sup=(*network).layer_order[level+1];    /* next level */
  614.     nb_neuron_sup=(*network).nb_n_layer[lay_sup];/* nb of neuron in lay_sup */
  615.     for (neuron=0; neuron<=nb_neuron;neuron++)
  616.       for (n=0; n<=nb_neuron_sup; n++)
  617.         (*network).inter[level][neuron][n]=Rnd(0.5)-0.25;
  618.     }
  619. }
  620.  
  621. void init_0_network(NETWORKS  *network)
  622.                 /* initializes a zero network */
  623. {
  624.   int neuron,
  625.       layer,
  626.       level,
  627.       n,
  628.       lay_sup,nb_lev,nb_neuron,nb_neuron_sup;
  629.            
  630.   for (layer=0; layer<=(*network).nb_layers; layer++)
  631.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  632.     {
  633.       (*network).neuron[neuron][layer].sum=0;
  634.       (*network).neuron[neuron][layer].state=0;
  635.       (*network).neuron[neuron][layer].loc_err=0;
  636.        
  637.       for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  638.         (*network).neuron[neuron][layer].intra[n]=0;
  639.     }
  640.   nb_lev=(*network).nb_levels-1;                /* nb of levels except the last */   
  641.   for (level=0; level<=nb_lev; level++)
  642.     {
  643.     layer=(*network).layer_order[level];        /* layer No level */
  644.     nb_neuron=(*network).nb_n_layer[layer];     /* nb of neuron in level */
  645.     lay_sup=(*network).layer_order[level+1];    /* next level */
  646.     nb_neuron_sup=(*network).nb_n_layer[lay_sup];
  647.     for (neuron=0; neuron<=nb_neuron;neuron++)
  648.       for (n=0; n<=nb_neuron_sup; n++)
  649.         (*network).inter[level][neuron][n]=0;
  650.     }
  651. }
  652.  
  653.  
  654. void init_flag_network(NETWORKS  *network,int activity,int interconnection,int bias,int tempering)
  655.                 /* initializes flags for a net */
  656. {
  657.   int neuron,
  658.       layer;
  659.             
  660.   (*network).tempering=tempering;
  661.   for (layer=0; layer<=(*network).nb_layers; layer++)
  662.   {
  663.     (*network).flag[layer].interconnection=interconnection;
  664.     (*network).flag[layer].bias=bias;
  665.   }
  666.     
  667.   for (layer=0; layer<=(*network).nb_layers; layer++)  
  668.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  669.     {
  670.  
  671.       (*network).neuron[neuron][layer].flag.activity=activity;
  672.       if (activity==0)
  673.         (*network).neuron[neuron][layer].state=0;
  674.       if (bias==0)
  675.         (*network).neuron[neuron][layer].bias=0;
  676.     }    
  677. }
  678.  
  679.  
  680. void init_var_network(NETWORKS  *network,
  681.                         float err_threshold,
  682.                         float beta,
  683.                         float coefficient,
  684.                         float coef_out,
  685.                         float high_threshold,
  686.                         float low_threshold,
  687.                         float weight_threshold,
  688.                         float threshold,
  689.                         float noise,
  690.                         float high_state,
  691.                         float low_state,
  692.                         float t_max,
  693.                         float t_min,
  694.                         float cte)
  695. {
  696.   (*network).err_threshold=err_threshold*(*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]];
  697.   (*network).beta=beta;
  698.   (*network).coefficient=coefficient;
  699.   (*network).coef_out=coef_out;
  700.   (*network).high_threshold=threshold+high_threshold/2/beta;
  701.   (*network).low_threshold=threshold+low_threshold/2/beta;
  702.   (*network).weight_threshold=weight_threshold;
  703.   (*network).threshold=threshold;
  704.   (*network).noise=noise;
  705.   (*network).high_state=high_state;
  706.   (*network).low_state=low_state;
  707.  
  708.   (*network).t_tempering_max=t_max;
  709.   (*network).t_tempering_min=t_min;
  710.   (*network).cte_tempering=cte;
  711.   (*network).energy=0;
  712. }
  713.  
  714. /* ------------------------------------------------------------ */
  715. /*                       infos                                  */
  716. /* ------------------------------------------------------------ */
  717.  
  718.  
  719. float compare_output(NETWORKS  *network,float output[])
  720. {       /* compare the output to the one expected */
  721.   int neuron,
  722.       layer=(*network).layer_order[(*network).nb_levels];
  723.   float err_tot=0,
  724.         error;
  725.  
  726.   for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  727.   {
  728.     error=(*network).neuron[neuron][layer].state-output[neuron];
  729.     err_tot+=0.5*error*error;
  730.   }
  731.   return(err_tot);
  732. }
  733.  
  734. float learn_verify(NETWORKS  *network,int list_prototypes[],int size_list,float inputs[],float outputs[])
  735. {       /* verify the learning for each prototype */
  736.   int k,j,NCin,NCout;
  737.   float err_max=0,err;
  738.   float input[NB_N_LAYER_MAXI],
  739.         output[NB_N_LAYER_MAXI];
  740.         
  741.                 /* nb of neurons in the 1st and last level */
  742.   NCin=(*network).nb_n_layer[(*network).layer_order[0]];
  743.   NCout=(*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]];
  744.  
  745.   for (k=0; k<=size_list; k++)
  746.   {
  747.   for (j=0; j<=NCin; j++)
  748.   input[j]=inputs[list_prototypes[k]*(NCin+1)+j];
  749.   for (j=0; j<=NCout; j++)
  750.   output[j]=outputs[list_prototypes[k]*(NCout+1)+j];
  751.  
  752.   network_state(network,input);
  753.   err=compare_output(network,output);
  754.   printf("\nFinal error lot %2i : %4.2f (%%)",k,err/NCout*100);
  755.   if (err_max<err) err_max=err;
  756.   }
  757.   return(err_max);
  758. }
  759.  
  760. float sqr_sum(NETWORKS  *network)      /* sends back the sum(sqr(links)) */
  761. {
  762.   int neuron,layer,n,level,layer_1;
  763.   float sum2=0;
  764.  
  765.   for (layer=0; layer<=(*network).nb_layers; layer++)
  766.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  767.     {
  768.       sum2+=sqr((*network).neuron[neuron][layer].bias);
  769.       for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  770.         sum2+=sqr((*network).neuron[neuron][layer].intra[n]);  
  771.     }
  772.   for (level=1; level<=(*network).nb_levels; level++)
  773.   {
  774.     layer=(*network).layer_order[level];
  775.     layer_1=(*network).layer_order[level-1];
  776.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  777.       for (n=0; n<=(*network).nb_n_layer[layer_1]; n++)
  778.         sum2+=sqr((*network).inter[level-1][n][neuron]);
  779.   }
  780.   return(sum2);   
  781. }
  782.  
  783.  
  784. void print_network(NETWORKS  *network)
  785. {
  786.   int neuron,level,layer;
  787.   float pot,state,loc_err,bias;
  788.   
  789.   printf("\nNetwork state:  sum, state, loc_err, bias");
  790.   for (level=0 ;level<=(*network).nb_levels; level++)
  791.   {
  792.     layer=(*network).layer_order[level];
  793.     printf("\n----------------------------------------------------\n");
  794.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  795.     {
  796.       pot=(*network).neuron[neuron][layer].sum;
  797.       printf(" %4.2f ",pot);
  798.     }
  799.     printf("\n");
  800.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  801.     {
  802.       state=(*network).neuron[neuron][layer].state;  
  803.       printf(" %4.2f ",state);
  804.     }
  805.     printf("\n");
  806.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  807.     {
  808.       loc_err=(*network).neuron[neuron][layer].loc_err;  
  809.       printf(" %4.2f ",loc_err);
  810.     }
  811.     printf("\n");
  812.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  813.     {
  814.       bias=(*network).neuron[neuron][layer].bias;  
  815.       printf(" %4.2f ",bias);
  816.     }
  817.   }
  818.   printf("\n----------------------------------------------------\n\n");
  819.   printf("\n <RETURN>");
  820.   getchar();
  821.  
  822. void info_struct_network(NETWORKS  *network)
  823. {
  824.   int i;
  825.  
  826.   printf("\n----------------- INFO STRUCTURE NETWORK -------------------\n\n");
  827.   printf("Memory size: %7.1f o\n",(float)sizeof(NETWORKS));
  828.   printf("Number of layers: %i\n",(*network).nb_layers+1);
  829.   printf("Number of levels: %i\n",(*network).nb_levels+1);
  830.   printf("\n");
  831.  
  832.   for (i=0; i<=(*network).nb_layers; i++)
  833.   {
  834.     printf("  Layer %2i, %3i neurons. Model ",i,(*network).nb_n_layer[i]+1);
  835.     if ((*network).flag[i].interconnection)
  836.       printf("Hopfield.\n");
  837.     else
  838.       printf("Perceptron.\n");
  839.   }    
  840.   printf("\n");
  841.   printf("The levels of the network are the layers:\n   -> ");
  842.   for (i=0; i<=(*network).nb_levels; i++)
  843.     printf(" %i ",(*network).layer_order[i]);     
  844.   printf("\n\n");
  845.   
  846.   printf("\n <RETURN>");
  847.   getchar();
  848. }
  849.  
  850. void info_vars_network(NETWORKS *network)
  851. {
  852.   float s,
  853.         s1=0,
  854.         s2=0,
  855.         sqr1=0,
  856.         sqr2=0;
  857.   int i=0,j=0,neuron,layer,n,level,layer_1;
  858.   
  859.   printf("\n---------------- INFO VARIABLES NETWORK -------------------\n");
  860.   printf("\n");
  861.   printf("Temperature: %5.2f\n",1/(*network).beta);
  862.   printf("Learning improving coefficient: %4.2f\n",(*network).coefficient);
  863.   printf("Threshold error on learning end: %4.3f (%3.1f %%)\n",(*network).err_threshold,
  864.   (*network).err_threshold/(*network).nb_n_layer[(*network).layer_order[(*network).nb_levels]]*100);
  865.   printf("High neuron state: %4.2f\n",(*network).high_state);
  866.   printf("Low neuron state : %4.2f\n",(*network).low_state);
  867.   printf("High threshold neuron potential: %4.2f\n",(*network).high_threshold);
  868.   printf("Low threshold neuron potential : %4.2f\n",(*network).low_threshold);
  869.   printf("Link threshold          : %4.2f\n",(*network).weight_threshold);
  870.   printf("Bascule neuron threshold: %4.2f\n",(*network).threshold);
  871.  
  872.   printf("Mean intra-layer link (Hopfield):");
  873.   for (layer=0; layer<=(*network).nb_layers; layer++)
  874.     for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  875.     {
  876.       s=(*network).neuron[neuron][layer].bias;
  877.       s1+=s;
  878.       sqr1+=sqr(s);
  879.       i++;
  880.       if ((*network).flag[layer].interconnection)
  881.         for (n=0; n<=(*network).nb_n_layer[layer]; n++)
  882.         {
  883.           s=(*network).neuron[neuron][layer].intra[n];
  884.           s1+=s;
  885.           sqr1+=sqr(s);
  886.           i++;
  887.         }
  888.     }
  889.   printf(" %5.3f\n\n",s1/i);
  890.  
  891.   if ((*network).nb_levels>0)
  892.   {
  893.     printf("Mean inter-layer link (Perceptron):");
  894.     for (level=1; level<=(*network).nb_levels; level++)
  895.     {
  896.       layer=(*network).layer_order[level];
  897.       layer_1=(*network).layer_order[level-1];
  898.       for (neuron=0; neuron<=(*network).nb_n_layer[layer]; neuron++)
  899.         for (n=0; n<=(*network).nb_n_layer[layer_1]; n++)
  900.         {
  901.           s=(*network).inter[level-1][n][neuron];
  902.           s2+=s;
  903.           sqr2+=sqr(s);
  904.           j++;
  905.         }
  906.     }
  907.     printf("%5.3f\n\n",s2/j);
  908.   }
  909.   printf("Mean global link: %5.3f\n",(s1+s2)/(i+j));
  910.   printf("Sum of intra-layer link square: %5.3f\n",sqr1);
  911.   printf("Sum of inter-layer link square: %5.3f\n",sqr2);
  912.   printf("\n");
  913.   printf("Network energy: %5.3f\n",(*network).energy);
  914.   printf("\n\n");
  915.  
  916.   printf("\n <RETURN>");
  917.   getchar();
  918. }
  919.  
  920. /* ------------------------------------------------------------ */
  921. /*                      END of module                           */
  922. /* ------------------------------------------------------------ */
  923.